<template>
  <div class="vita-cell">
    <div class="vita-cell-hd">
      <label v-if="title" class="vita-label">{{title}}</label>
    </div>
    <div class="vita-cell-bd vita-cell-primary">
      <input class="vita-input" :type="type" :pattern="pattern" placeholder="{{placeholder}}" v-model="value" @blur="blurHanlder" v-focus="focus"/>
    </div>
    <div class="vita-cell-ft">
      <vita-icon type="clear" v-show="showClear && value" @click="clearValue"></vita-icon>
      <vita-icon type="warn" v-show="!equalWith && (touched && !valid && error)"></vita-icon>
      <vita-icon type="success" v-show="equalWith && equalWith===value && valid"></vita-icon>
    </div>
  </div>
</template>

<script>

  import Base from './libs/base.js'
  import VitaIcon from './Icon.vue'
  import { isURL, isMobilePhone, isEmail } from 'validator'
  import { focus, focusAuto } from 'vue-focus'

  const validators = {
    ip: {
      fn: isURL,
      message: 'IP地址格式不正确'
    },
    mobile: {
      fn: isMobilePhone,
      message: '手机号码格式不正确'
    },
    email: {
      fn: isEmail,
      message: '邮箱地址格式不正确'
    }
  }
  
  export default {

    directives: {
      focus, focusAuto
    },

    components: {
      VitaIcon
    },

    mixins: [Base],

    props: {
      type: {
        type: String,
      },
      title: {
        type: String,
        required: false
      },
      value: {
        type: String,
        default: '',
        twoWay: true
      },
      showClear: {
        type: Boolean,
        default: true
      },
      equalWith: {
        required: false,
        type: String
      },
      minLength: {
        required: false,
        type: Number
      },
      maxLength: {
        required: false,
        type: Number
      },
      //Email,mobile number, ip, url
      validateType: {
        required: false,
        type: String
      }
    },

    data() {
      return {
        error: String,
        focus: false
      }
    },
    
    methods: {
      blurHanlder() {
        this.touched = true
        this.validate()
      },

      focusHandler() {

      },

      clearValue() {
        this.value = ''
        this.focus = true
      },

      updateError() {
        let key = Object.keys(this.errors)[0]
        this.error = this.errors[key]
      }, 

      validate() {
        if (this.equalWith) {
          return this.validateEqual()
        }

        let errors = this.errors = {}

        if (!this.value && !this.required) {
          return this.valid = true
        }
        // 设置为必填项时，检查
        if (!this.value && this.required) {
          this.valid = false
          return this.errors.required = '必填项'
        }

        const validator = validators[this.validateType]
        // 指定validateType时，检查
        if (validator) {
          this.valid = validator['fn'](this.value)
          if (!this.valid) { 
            return this.errors.format = validator['message']
          } else {
            delete this.errors.format
          }
        }
        // 指定最少长度，检查
        if (this.minLength) {
          if (this.value.length < this.minLength) {
            this.valid = false
            let min = this.minLength
            return this.errors.minLength = `至少输入${min}个字符`
          } else {
            delete this.errors.minLength
          }
        }
        // 指定最大长度，检查
        if (this.maxLength) {
          if (this.value.length > this.maxLength) {
            this.valid = false
            let max = this.maxLength
            return this.errors.maxLength = `最多输入${max}个字符`
          } else {
            delete this.errors.maxLength
          }
        }

        // 通过所有检查后，该值通过校验
        this.valid = true

      },
      // 设置equalWith之后的检查
      validateEqual() {
        let willCheck = this.dirty || this.value.length >= this.equalWith.length
        if (willCheck && this.value !== this.equalWith) {
          this.valid = false
          this.errors.equal = '输入不一致'
        } else {
          this.value = false
          delete this.errors.equal
        }
      }
    },

    watch: {
      valid() {
        this.updateError()
      },
      value(newVal) {
        if (this.equalWith) {
          this.validateEqual()
        } else {
          this.validate()
        }
      }
    }

  }

</script>